package com.hmall.order.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.client.ItemClient;
import com.hmall.client.UserClient;
import com.hmall.common.dto.Address;
import com.hmall.common.pojo.Item;
import com.hmall.common.pojo.User;
import com.hmall.order.mapper.OrderDetailMapper;
import com.hmall.order.mapper.OrderLogisticsMapper;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.CreateOrder;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.service.IOrderService;
import com.hmall.order.threadlocal.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {


    @Autowired
    private ItemClient itemClient;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private UserClient userClient;

    @Autowired
    private OrderLogisticsMapper orderLogisticsMapper;
    /**
     * 创建订单
     *
     * @param createOrder
     * @return
     */
    @Override
    public Long createOrder(CreateOrder createOrder) {
        //1.根据雪花算法生成订单id
        String ip = NetUtil.getLocalhostStr();
        int ipHash = ip.hashCode();
        // 计算 workerId 和 datacenterId
        int workerId = ipHash & 31; // 取低5位作为 workerId
        int datacenterId = (ipHash >> 5) & 31; // 右移5位后取低5位作为 datacenterId
        Snowflake snowflake = IdUtil.createSnowflake(workerId, datacenterId);
        // 生成下一个ID
        long id = snowflake.nextId();
        //2.商品微服务提供FeignClient，实现根据id查询商品的接口
        //3.根据itemId查询商品信息
        Item item = itemClient.selectById(createOrder.getItemId().toString());
        //4.基于商品价格、购买数量计算商品总价：totalFee
        Long totalFee = createOrder.getNum()*item.getPrice();
        //5.封装Order对象，初始status为未支付
        //订单的状态，1、未付款 2、已付款,未发货 3、已发货,未确认 4、确认收货，交易成功 5、交易取消，订单关闭 6、交易结束，已评价'
        Order order = Order.builder()
                .status(1)
                .id(id)
                .totalFee(totalFee)
                .userId(Long.valueOf(UserContext.getUserId()))
                .paymentType(3)
                .createTime(new Date()).build();

        //6.将Order写入数据库tb_order表中
        orderMapper.insert(order);
        //7.将商品信息、orderId信息封装为OrderDetail对象，写入tb_order_detail表
        OrderDetail orderDetail = OrderDetail.builder()
                .orderId(id)
                .itemId(item.getId())
                .num(createOrder.getNum())
                .name(item.getName())
                .price(order.getTotalFee())
                .spec(item.getSpec())
                .image(item.getImage())
                .createTime(new Date()).build();
        orderDetailMapper.insert(orderDetail);
        //8.将user-service的根据id查询地址接口封装为FeignClient
        //9.根据addressId查询user-service服务，获取地址信息
        Address address = userClient.findAddressById(createOrder.getAddressId());
        //10.将地址封装为OrderLogistics对象，写入tb_order_logistics表
        String userId = UserContext.getUserId();
        User user = userClient.getById(Long.valueOf(userId));
        OrderLogistics orderLogistics = OrderLogistics.builder()
                .orderId(id)
                .contact(user.getUsername())
                .phone(user.getPhone())
                .province(address.getProvince())
                .city(address.getCity())
                .town(address.getTown())
                .street(address.getStreet())
                .createTime(new Date())
                .build();
        orderLogisticsMapper.insert(orderLogistics);
        //11.在item-service提供减库存接口，并编写FeignClient
        //12.调用item-service的减库存接口
        itemClient.stockNum(item.getId(),createOrder.getNum());
        return id;
    }
}
